// http客户端
#include <workflow/WFFacilities.h>//include WFFacilities library to provide asynchronous task and event processing function
#include <workflow/WFTaskFactory.h>//include WFTaskFactory library used to create HTTP task
#include <workflow/HttpUtil.h>//include HttpUtil library to provide http tools
#include <signal.h>//include signal library used to processing signal
#include <iostream>
using std::cout;
using std::cerr;

//create a variable of waitGroup
//used to synchronize waiting task complete
static WFFacilities::WaitGroup waitGroup(1);

//rigister a signal function
//used to processing SIGINT
void sighandler(int signum){
    waitGroup.done();//waitGroup complete
    cout << "done\n";
}

//httpTask callback function
//used to process http request and response
void httpCallback(WFHttpTask *task){
	protocol::HttpRequest *req = task->get_req();//to get http request messages
	protocol::HttpResponse *resp = task->get_resp(); //to get http response messages
	int state = task->get_state();//to get task state
	int error = task->get_error();//to get task error code

    //processing difference type
	switch(state){
	case WFT_STATE_SYS_ERROR://system error
		cerr <<"system error: " << strerror(error) << "\n";
		break;
	case WFT_STATE_DNS_ERROR://DNS parse error
		cerr <<"DNS error: " << gai_strerror(error) << "\n";
		break;
	case WFT_STATE_SSL_ERROR://SSL error
		cerr <<"SSL error: " << error << "\n";
		break;
	case WFT_STATE_TASK_ERROR://task error
		cerr <<"Task error: "<< error << "\n";
		break;
	case WFT_STATE_SUCCESS://task success
		break;
	}

    //if task failed
    //print failure messages
	if (state != WFT_STATE_SUCCESS){
		cerr <<"Failed. Press Ctrl-C to exit.\n";
		return;
	}

	//output http request messages
	cerr << req->get_method() << " "//request type
		 << req->get_http_version() << " "//http version
	     << req->get_request_uri() << "\n";//request uri
    
    //Iterate over the response headers and output each header's name and value
	protocol::HttpHeaderCursor reqCursor(req);
	std::string name;
	std::string value;
	while (reqCursor.next(name, value)){
        cerr << "name = " << name << " value = " << value << "\n";
    }

	//output http response messages
	cerr << resp->get_http_version() << " "//response http version
		 << resp->get_status_code()  << " "//response status code
		 << resp->get_reason_phrase() << "\n";//response status phrase
    
    //iterate response headers and output each header's name and value
	protocol::HttpHeaderCursor respCursor(resp);
	while (respCursor.next(name, value)){
        cerr << "name = " << name << " value = " << value << "\n";
    }
	
    //get and output response body context
	const void *body;//response body pointer
	size_t body_len;//response body length
	resp->get_parsed_body(&body, &body_len);//get parsed response body
    cerr << static_cast<const char *>(body) << "\n";//output response context
}
int main(){
    signal(SIGINT,sighandler);//rigister signal handle function,to handle Ctrl + C
   
    //create a HTTP task, target URL is "http://www.baidu.com"
    //set link and overtime time
    WFHttpTask * httpTask = WFTaskFactory::create_http_task(
        "http://www.baidu.com",//request URL
        10, //link overtime (second)
        10, //request overtime (second)
        httpCallback// callback function
    );
    
    httpTask->start();//start HTTP task
    waitGroup.wait();//wait for task finished
    cout << "finished!\n";
    return 0;
}
